package com.jade.editor.object.editors;


import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.jade.editor.object.editors.nodes.Node;

public class ObjectModel {
	
	private Point _dist = null;															//DONE21
	private ArrayList<Node> _nodeList = new ArrayList<Node>();							//DONE21
	private boolean _connected = false;													//DONE21
	
	private RGB _borderColor = null;													//DONE21
	private RGB _connectionColor = null;												//DONE21
	private RGB _selectionColor = null;													//DONE21
	private RGB _fillColor = null;														//DONE21
	
	private Point _pole = null;															//DONE21
	private boolean _hasPole = false;													//DONE21
	
	private RGB _poleColor = null;														//DONE21
	private RGB _poleSelectionColor = null;												//DONE21
	
	private String _imgPath = null;														//DONE21
	private Point _imgLocation = null;													//DONE21
	
	private RGB _bgColor = null;														//DONE21
	
	private ArrayList<String> _holeList = new ArrayList<String>();						//DONE
	private HashMap<String, Double> _holeAngleMap = new HashMap<String, Double>();		//DONE
	private HashMap<String, Point> _holeLocationMap = new HashMap<String, Point>();		//DONE
	private HashMap<String, String> _holePathMap = new HashMap<String, String>();		//DONE
	private RGB _holeColor = null;														//DONE
	
	private String _aniPath = null;														//DONE
	private Point _aniLocation = null;													//DONE
	private double _aniAngle = 0.0;														//DONE
	private RGB _aniColor = null;														//DONE
	
	private String _path = null;
	
	private ArrayList<Point> _alist = new ArrayList<Point>();
	
	
	public ObjectModel(String path){
		terminateData();
		_path = path;
		load();
	}
	
	public void setAniPointsList(ArrayList<Point> lst){
		_alist = lst;
	}
	
	public void load(String path){
		terminateData();
		_path = path;
		load();
	}
	
	public String getPath(){
		return _path;
	}
	
	public Point getDistance(){
		return _dist;
	}
	
	public void setDistance(Point distance){
		_dist = distance;
	}

	public boolean getConnected(){
		return _connected;
	}
	
	public void setConnected(boolean b){
		_connected = b;
	}
	
	public RGB getBorderColor(){
		return _borderColor;
	}
	
	public void setBorderColor(RGB color){
		_borderColor = color;
	}
	
	public RGB getConnectionColor(){
		return _connectionColor;
	}
	
	public void setConnectionColor(RGB color){
		_connectionColor = color;
	}
	
	public RGB getSelectionColor(){
		return _selectionColor;
	}
	
	public void setSelectionColor(RGB color){
		_selectionColor = color;
	}
	
	public RGB getFillColor(){
		return _fillColor;
	}
	
	public void setFillColor(RGB color){
		_fillColor = color;
	}
	
	public RGB getPoleColor(){
		return _poleColor;
	}
	
	public void setPoleColor(RGB color){
		_poleColor = color;
	}
	
	public RGB getPoleSelectionColor(){
		return _poleSelectionColor;
	}
	
	public void setPoleSelectionColor(RGB color){
		_poleSelectionColor = color;
	}
	
	public RGB getBGColor(){
		return _bgColor;
	}
	
	public void setBGColor(RGB color){
		_bgColor = color;
	}
	
	public RGB getHoleColor(){
		return _holeColor;
	}
	
	public void setHoleColor(RGB color){
		_holeColor = color;
	}
	
	public RGB getAniColor(){
		return _aniColor;
	}
	
	public void setAniColor(RGB color){
		_aniColor = color;
	}
	
	public Point getPole(){
		return _pole;
	}
	
	public void setPole(Point pole){
		_pole = pole;
	}
	
	public boolean hasPole(){
		return _hasPole;
	}
	
	public void hasPole(boolean b){
		_hasPole = b;
	}
	
	public void setPoleExist(boolean b){
		_hasPole = b;
	}
	
	public String getBGImagePath(){
		return _imgPath;
	}
	
	public void setBGImagePath(String path){
		_imgPath = path;
	}
	
	public Point getBGImageLocation(){
		return _imgLocation;
	}
	
	public void setBGImageLocation(Point p){
		_imgLocation = p;
	}
	
	public String getAniPath(){
		return _aniPath;
	}
	
	public void setAniPath(String path){
		_aniPath = path;
	}
	
	public Point getAniLocation(){
		return _aniLocation;
	}
	
	public void setAniLocation(Point loc){
		_aniLocation = loc;
	}
	
	public double getAniAngle(){
		return _aniAngle;
	}
	
	public void setAniAngle(double angle){
		_aniAngle = angle;
	}
	
	public ArrayList<String> getHoleList(){
		return _holeList;
	}
	
	public HashMap<String, Double> getHoleAngleMap(){
		return _holeAngleMap;
	}
	
	public HashMap<String, Point> getHolesLocationMap(){
		return _holeLocationMap;
	}
	
	public HashMap<String, String> getHolePathMap(){
		return _holePathMap;
	}
	
	public double getHoleAngle(String name){
		return _holeAngleMap.get(name);
	}
	
	public Point getHoleLocation(String name){
		return _holeLocationMap.get(name);
	}
	
	public String getHolePath(String name){
		return _holePathMap.get(name);
	}
	
	public void setHoleNameList(ArrayList<String> list){
		_holeList = list;
	}
	
	public void setHoleAngleMap(HashMap<String, Double> map){
		_holeAngleMap = map;
	}
	
	public void setHoleLocationMap(HashMap<String, Point> map){
		_holeLocationMap = map;
	}
	
	public void setHolePathList(HashMap<String, String> map){
		_holePathMap = map;
	}
	
	public void setHoleData(ArrayList<String> nameList, HashMap<String, Point> locationMap){
		_holeList = nameList;
		_holeLocationMap = locationMap;
	}
	
	public void setHoleData(ArrayList<String> nameList, HashMap<String, Point> locationMap, HashMap<String, Double> angleMap){
		_holeList = nameList;
		_holeLocationMap = locationMap;
		_holeAngleMap = angleMap;
	}
	
	public void setHoleData(ArrayList<String> nameList, HashMap<String, Point> locationMap, HashMap<String, String> pathMap, boolean any){
		_holeList = nameList;
		_holeLocationMap = locationMap;
		_holePathMap = pathMap;
	}
	
	public void setHoleData(ArrayList<String> nameList, HashMap<String, Point> locationMap, HashMap<String, Double> angleMap, HashMap<String, String> pathMap){
		_holeList = nameList;
		_holeLocationMap = locationMap;
		_holeAngleMap = angleMap;
		_holePathMap = pathMap;
	}
	
	public ArrayList<Node> getNodeList(){
		return _nodeList;
	}
	
	public void setNodeList(ArrayList<Node> list){
		_nodeList = list;
	}
	
	
	
	public void terminateData(){
		_dist = null;
		_connected = false;
		_borderColor = null;
		_connectionColor = null;
		_selectionColor = null;
		_fillColor = null;
		_poleColor = null;
		_poleSelectionColor = null;
		_bgColor = null;
		_holeColor = null;
		_aniColor = null;
		_pole = null;
		_hasPole = false;
		_imgPath = null;
		_imgLocation = null;
		_aniPath = null;
		_aniLocation = null;
		_aniAngle = 0.0;
		_holeList.clear();
		_holeAngleMap.clear();
		_holeLocationMap.clear();
		_holePathMap.clear();
		_nodeList.clear();
		_alist.clear();
	}
	
	public void save(){
		
		File file = new File(_path);
		
		try{
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			Document doc = docBuilder.newDocument();
			
			//---OBJECT
			Element rootElement = doc.createElement("OBJECT");
			//---DISTANCE
			if(_dist != null){
				rootElement.setAttribute("x", Integer.toString(_dist.x));
				rootElement.setAttribute("y", Integer.toString(_dist.y));
			}
			//---CONNECTED
			if (_connected)
				rootElement.setAttribute("connected", "1");
			else
				rootElement.setAttribute("connected", "0");
			doc.appendChild(rootElement);
			
			
			//---COLORS
			Element colorElement = doc.createElement("COLOR_LIST");
			//---BORDER COLOR
			if(_borderColor != null){
				Element borderColorElement = doc.createElement("BORDER_COLOR");
				borderColorElement.setAttribute("r", Integer.toString(_borderColor.red));
				borderColorElement.setAttribute("g", Integer.toString(_borderColor.green));
				borderColorElement.setAttribute("b", Integer.toString(_borderColor.blue));
				colorElement.appendChild(borderColorElement);
			}
			//---CONNECTION COLOR
			if(_connectionColor != null){
				Element connectionColorElement = doc.createElement("CONNECTION_COLOR");
				connectionColorElement.setAttribute("r", Integer.toString(_connectionColor.red));
				connectionColorElement.setAttribute("g", Integer.toString(_connectionColor.green));
				connectionColorElement.setAttribute("b", Integer.toString(_connectionColor.blue));
				colorElement.appendChild(connectionColorElement);
			}
			//---SELECTION COLOR
			if(_selectionColor != null){
				Element selectionColorElement = doc.createElement("SELECTION_COLOR");
				selectionColorElement.setAttribute("r", Integer.toString(_selectionColor.red));
				selectionColorElement.setAttribute("g", Integer.toString(_selectionColor.green));
				selectionColorElement.setAttribute("b", Integer.toString(_selectionColor.blue));
				colorElement.appendChild(selectionColorElement);
			}
			//---FILL COLOR
			if(_fillColor != null){
				Element fillColorElement = doc.createElement("FILL_COLOR");
				fillColorElement.setAttribute("r", Integer.toString(_fillColor.red));
				fillColorElement.setAttribute("g", Integer.toString(_fillColor.green));
				fillColorElement.setAttribute("b", Integer.toString(_fillColor.blue));
				colorElement.appendChild(fillColorElement);
			}
			//---POLE COLOR
			if(_poleColor != null){
				Element poleColorElement = doc.createElement("POLE_COLOR");
				poleColorElement.setAttribute("r", Integer.toString(_poleColor.red));
				poleColorElement.setAttribute("g", Integer.toString(_poleColor.green));
				poleColorElement.setAttribute("b", Integer.toString(_poleColor.blue));
				colorElement.appendChild(poleColorElement);
			}
			//---POLE SELECTION COLOR
			if(_poleSelectionColor != null){
				Element poleSelectionColorElement = doc.createElement("POLE_SELECTION_COLOR");
				poleSelectionColorElement.setAttribute("r", Integer.toString(_poleSelectionColor.red));
				poleSelectionColorElement.setAttribute("g", Integer.toString(_poleSelectionColor.green));
				poleSelectionColorElement.setAttribute("b", Integer.toString(_poleSelectionColor.blue));
				colorElement.appendChild(poleSelectionColorElement);
			}
			//---BG COLOR
			if(_bgColor != null){
				Element bgColorElement = doc.createElement("BG_COLOR");
				bgColorElement.setAttribute("r", Integer.toString(_bgColor.red));
				bgColorElement.setAttribute("g", Integer.toString(_bgColor.green));
				bgColorElement.setAttribute("b", Integer.toString(_bgColor.blue));
				colorElement.appendChild(bgColorElement);
			}
			//---HOLE COLOR
			if(_holeColor != null){
				Element holeColorElement = doc.createElement("HOLE_COLOR");
				holeColorElement.setAttribute("r", Integer.toString(_holeColor.red));
				holeColorElement.setAttribute("g", Integer.toString(_holeColor.green));
				holeColorElement.setAttribute("b", Integer.toString(_holeColor.blue));
				colorElement.appendChild(holeColorElement);
			}
			//---ANI COLOR
			if(_aniColor != null){
				Element aniColorElement = doc.createElement("ANI_COLOR");
				aniColorElement.setAttribute("r", Integer.toString(_aniColor.red));
				aniColorElement.setAttribute("g", Integer.toString(_aniColor.green));
				aniColorElement.setAttribute("b", Integer.toString(_aniColor.blue));
				colorElement.appendChild(aniColorElement);
			}
			rootElement.appendChild(colorElement);
			
			//---POLE
			if(_pole != null){
				Element poleElement = doc.createElement("POLE");
				poleElement.setAttribute("x", Integer.toString(_pole.x));
				poleElement.setAttribute("y", Integer.toString(_pole.y));
				if(_hasPole)
					poleElement.setAttribute("hasPole", "1");
				else
					poleElement.setAttribute("hasPole", "0");
				rootElement.appendChild(poleElement);
			}
			
			//---BG IMAGE
			if(_imgPath != null && !_imgPath.equals("")){
				File imgFile = new File(_imgPath);
				
				Element bgImgElement = doc.createElement("BGIMAGE");
				bgImgElement.setAttribute("name", imgFile.getName());
				if (_imgLocation != null){
					bgImgElement.setAttribute("x", Integer.toString(_imgLocation.x));
					bgImgElement.setAttribute("y", Integer.toString(_imgLocation.y));
				}
				else{
					bgImgElement.setAttribute("x", "0");
					bgImgElement.setAttribute("y", "0");
				}
				rootElement.appendChild(bgImgElement);
			}
			
			//---ANISOTROPY
			if(_aniPath != null && !_aniPath.equals("")){
				File aniFile = new File(_aniPath);
				
				Element aniElement = doc.createElement("ANISOTROPY");
				aniElement.setAttribute("name", aniFile.getName());
				
				if(_aniLocation != null){
					aniElement.setAttribute("x", Integer.toString(_aniLocation.x));
					aniElement.setAttribute("y", Integer.toString(_aniLocation.y));
				}
				else{
					aniElement.setAttribute("x", "0");
					aniElement.setAttribute("y", "0");
				}
				
				aniElement.setAttribute("angle", Double.toString(_aniAngle));
				rootElement.appendChild(aniElement);
				
				//---ANIPoints
				
				for(Point p : _alist){
					Element aElement = doc.createElement("POINT");
					aElement.setAttribute("x", Integer.toString(p.x));
					aElement.setAttribute("y", Integer.toString(p.y));
					
					aniElement.appendChild(aElement);
				}
			}
			
			//---HOLE LIST
			if(_holeList.size() > 0){
				Element holeListElement = doc.createElement("HOLE_LIST");
				for(String hole : _holeList){
					Element holeElement = doc.createElement("HOLE");
					
					holeElement.setAttribute("name", hole);
					if (_holeLocationMap.containsKey(hole)){
						holeElement.setAttribute("x", Integer.toString(_holeLocationMap.get(hole).x));
						holeElement.setAttribute("y", Integer.toString(_holeLocationMap.get(hole).y));
					}
					else{
						holeElement.setAttribute("x", "0");
						holeElement.setAttribute("y", "0");
					}
					
					if(_holeAngleMap.containsKey(hole))
						holeElement.setAttribute("angle", Double.toString(_holeAngleMap.get(hole)));
					else
						holeElement.setAttribute("angle", "0.0");
					
					holeListElement.appendChild(holeElement);
				}
				rootElement.appendChild(holeListElement);
			}
			
			//---NODE LIST
			if(_nodeList.size() > 0){
				
				Element nodeListElement = doc.createElement("NODE_LIST");
				
				for(Node n : _nodeList){
					Element nodeElement = doc.createElement("NODE");
					
					nodeElement.setAttribute("x", Integer.toString(n.x));
					nodeElement.setAttribute("y", Integer.toString(n.y));
					
					if (n.hasOutNode()){
						nodeElement.setAttribute("outx", Integer.toString(n.getOutNode().x));
						nodeElement.setAttribute("outy", Integer.toString(n.getOutNode().y));
					}
					
					if (n.hasInNode()){
						nodeElement.setAttribute("inx", Integer.toString(n.getInNode().x));
						nodeElement.setAttribute("iny", Integer.toString(n.getInNode().y));
					}
					
					nodeListElement.appendChild(nodeElement);
				}
				rootElement.appendChild(nodeListElement);
			}
			
			//---WRITE TO FILE
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(file);
	 
			transformer.transform(source, result);
			
		}
		catch(Exception e){
			e.printStackTrace();
			System.err.println("Cant save to file");
		}
	}
	
	public boolean save(IProgressMonitor monitor){
		monitor.beginTask("Saving File", 200);
		
		File file = new File(_path);
		
		try{
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			Document doc = docBuilder.newDocument();
			monitor.worked(10);
			
			//---OBJECT
			Element rootElement = doc.createElement("OBJECT");
			monitor.worked(10);
			
			//---DISTANCE
			if(_dist != null){
				rootElement.setAttribute("x", Integer.toString(_dist.x));
				rootElement.setAttribute("y", Integer.toString(_dist.y));
			}
			monitor.worked(10);
			
			//---CONNECTED
			if (_connected)
				rootElement.setAttribute("connected", "1");
			else
				rootElement.setAttribute("connected", "0");
			doc.appendChild(rootElement);
			monitor.worked(10);
			
			
			//---COLORS
			Element colorElement = doc.createElement("COLOR_LIST");
			monitor.worked(10);
			
			//---BORDER COLOR
			if(_borderColor != null){
				Element borderColorElement = doc.createElement("BORDER_COLOR");
				borderColorElement.setAttribute("r", Integer.toString(_borderColor.red));
				borderColorElement.setAttribute("g", Integer.toString(_borderColor.green));
				borderColorElement.setAttribute("b", Integer.toString(_borderColor.blue));
				colorElement.appendChild(borderColorElement);
			}
			monitor.worked(10);
			
			//---CONNECTION COLOR
			if(_connectionColor != null){
				Element connectionColorElement = doc.createElement("CONNECTION_COLOR");
				connectionColorElement.setAttribute("r", Integer.toString(_connectionColor.red));
				connectionColorElement.setAttribute("g", Integer.toString(_connectionColor.green));
				connectionColorElement.setAttribute("b", Integer.toString(_connectionColor.blue));
				colorElement.appendChild(connectionColorElement);
			}
			monitor.worked(10);
			
			//---SELECTION COLOR
			if(_selectionColor != null){
				Element selectionColorElement = doc.createElement("SELECTION_COLOR");
				selectionColorElement.setAttribute("r", Integer.toString(_selectionColor.red));
				selectionColorElement.setAttribute("g", Integer.toString(_selectionColor.green));
				selectionColorElement.setAttribute("b", Integer.toString(_selectionColor.blue));
				colorElement.appendChild(selectionColorElement);
			}
			monitor.worked(10);
			
			//---FILL COLOR
			if(_fillColor != null){
				Element fillColorElement = doc.createElement("FILL_COLOR");
				fillColorElement.setAttribute("r", Integer.toString(_fillColor.red));
				fillColorElement.setAttribute("g", Integer.toString(_fillColor.green));
				fillColorElement.setAttribute("b", Integer.toString(_fillColor.blue));
				colorElement.appendChild(fillColorElement);
			}
			monitor.worked(10);
			
			//---POLE COLOR
			if(_poleColor != null){
				Element poleColorElement = doc.createElement("POLE_COLOR");
				poleColorElement.setAttribute("r", Integer.toString(_poleColor.red));
				poleColorElement.setAttribute("g", Integer.toString(_poleColor.green));
				poleColorElement.setAttribute("b", Integer.toString(_poleColor.blue));
				colorElement.appendChild(poleColorElement);
			}
			monitor.worked(10);
			
			//---POLE SELECTION COLOR
			if(_poleSelectionColor != null){
				Element poleSelectionColorElement = doc.createElement("POLE_SELECTION_COLOR");
				poleSelectionColorElement.setAttribute("r", Integer.toString(_poleSelectionColor.red));
				poleSelectionColorElement.setAttribute("g", Integer.toString(_poleSelectionColor.green));
				poleSelectionColorElement.setAttribute("b", Integer.toString(_poleSelectionColor.blue));
				colorElement.appendChild(poleSelectionColorElement);
			}
			monitor.worked(10);
			
			//---BG COLOR
			if(_bgColor != null){
				Element bgColorElement = doc.createElement("BG_COLOR");
				bgColorElement.setAttribute("r", Integer.toString(_bgColor.red));
				bgColorElement.setAttribute("g", Integer.toString(_bgColor.green));
				bgColorElement.setAttribute("b", Integer.toString(_bgColor.blue));
				colorElement.appendChild(bgColorElement);
			}
			monitor.worked(10);
			
			//---HOLE COLOR
			if(_holeColor != null){
				Element holeColorElement = doc.createElement("HOLE_COLOR");
				holeColorElement.setAttribute("r", Integer.toString(_holeColor.red));
				holeColorElement.setAttribute("g", Integer.toString(_holeColor.green));
				holeColorElement.setAttribute("b", Integer.toString(_holeColor.blue));
				colorElement.appendChild(holeColorElement);
			}
			monitor.worked(10);
			
			//---ANI COLOR
			if(_aniColor != null){
				Element aniColorElement = doc.createElement("ANI_COLOR");
				aniColorElement.setAttribute("r", Integer.toString(_aniColor.red));
				aniColorElement.setAttribute("g", Integer.toString(_aniColor.green));
				aniColorElement.setAttribute("b", Integer.toString(_aniColor.blue));
				colorElement.appendChild(aniColorElement);
			}
			rootElement.appendChild(colorElement);
			monitor.worked(10);
			
			//---POLE
			if(_pole != null){
				Element poleElement = doc.createElement("POLE");
				poleElement.setAttribute("x", Integer.toString(_pole.x));
				poleElement.setAttribute("y", Integer.toString(_pole.y));
				if(_hasPole)
					poleElement.setAttribute("hasPole", "1");
				else
					poleElement.setAttribute("hasPole", "0");
				rootElement.appendChild(poleElement);
			}
			monitor.worked(10);
			
			//---BG IMAGE
			if(_imgPath != null && !_imgPath.equals("")){
				File imgFile = new File(_imgPath);
				
				Element bgImgElement = doc.createElement("BGIMAGE");
				bgImgElement.setAttribute("name", imgFile.getName());
				if (_imgLocation != null){
					bgImgElement.setAttribute("x", Integer.toString(_imgLocation.x));
					bgImgElement.setAttribute("y", Integer.toString(_imgLocation.y));
				}
				else{
					bgImgElement.setAttribute("x", "0");
					bgImgElement.setAttribute("y", "0");
				}
				rootElement.appendChild(bgImgElement);
			}
			monitor.worked(10);
			
			//---ANISOTROPY
			if(_aniPath != null && !_aniPath.equals("")){
				
				Element aniElement = doc.createElement("ANISOTROPY");
				aniElement.setAttribute("name", _aniPath);
				
				if(_aniLocation != null){
					aniElement.setAttribute("x", Integer.toString(_aniLocation.x));
					aniElement.setAttribute("y", Integer.toString(_aniLocation.y));
				}
				else{
					aniElement.setAttribute("x", "0");
					aniElement.setAttribute("y", "0");
				}
				
				aniElement.setAttribute("angle", Double.toString(_aniAngle));
				
				//---ANIPoints
				
				for(Point p : _alist){
					Element aElement = doc.createElement("POINT");
					aElement.setAttribute("x", Integer.toString(p.x));
					aElement.setAttribute("y", Integer.toString(p.y));
					
					aniElement.appendChild(aElement);
				}
				
				rootElement.appendChild(aniElement);
			}
			monitor.worked(10);
			
			//---HOLE LIST
			if(_holeList.size() > 0){
				Element holeListElement = doc.createElement("HOLE_LIST");
				for(String hole : _holeList){
					Element holeElement = doc.createElement("HOLE");
					
					holeElement.setAttribute("name", hole);
					if (_holeLocationMap.containsKey(hole)){
						holeElement.setAttribute("x", Integer.toString(_holeLocationMap.get(hole).x));
						holeElement.setAttribute("y", Integer.toString(_holeLocationMap.get(hole).y));
					}
					else{
						holeElement.setAttribute("x", "0");
						holeElement.setAttribute("y", "0");
					}
					
					if(_holeAngleMap.containsKey(hole))
						holeElement.setAttribute("angle", Double.toString(_holeAngleMap.get(hole)));
					else
						holeElement.setAttribute("angle", "0.0");
					
					holeListElement.appendChild(holeElement);
				}
				rootElement.appendChild(holeListElement);
			}
			monitor.worked(10);
			
			//---NODE LIST
			if(_nodeList.size() > 0){
				
				Element nodeListElement = doc.createElement("NODE_LIST");
				
				for(Node n : _nodeList){
					Element nodeElement = doc.createElement("NODE");
					
					nodeElement.setAttribute("x", Integer.toString(n.x));
					nodeElement.setAttribute("y", Integer.toString(n.y));
					
					if (n.hasOutNode()){
						nodeElement.setAttribute("outx", Integer.toString(n.getOutNode().x));
						nodeElement.setAttribute("outy", Integer.toString(n.getOutNode().y));
					}
					
					if (n.hasInNode()){
						nodeElement.setAttribute("inx", Integer.toString(n.getInNode().x));
						nodeElement.setAttribute("iny", Integer.toString(n.getInNode().y));
					}
					
					nodeListElement.appendChild(nodeElement);
				}
				rootElement.appendChild(nodeListElement);
			}
			monitor.worked(10);
			
			//---WRITE TO FILE
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(file);
			
			transformer.transform(source, result);
			monitor.worked(10);
			monitor.done();
		}
		catch(Exception e){
			e.printStackTrace();
			System.err.println("Cant save to file");
			return false;
		}
		return true;
	}
	
	private void load(){
		File file = new File(_path);
		if(file.exists()){
			if(file.length() != 0){
			
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder;
				try {
					dBuilder = dbFactory.newDocumentBuilder();
					Document doc = dBuilder.parse(file);
					doc.getDocumentElement().normalize();
					
					if(doc.hasChildNodes()){
						if(doc.getDocumentElement().getNodeName().toLowerCase().indexOf("object") == 0){
							
							//---Node OBJECT HAS ATTRIBUTES---DISTANCE SET
							if (doc.getDocumentElement().hasAttribute("x") && doc.getDocumentElement().hasAttribute("y")){
								String xDistString = doc.getDocumentElement().getAttributeNode("x").getValue();
								String yDistString = doc.getDocumentElement().getAttributeNode("y").getValue();
								
								int xdist = Integer.parseInt(xDistString);
								int ydist = Integer.parseInt(yDistString);
								
								_dist = new Point(xdist, ydist);
							}
							
							//---CONNECTED SET
							if(doc.getDocumentElement().hasAttribute("connected")){
								String connectedString = doc.getDocumentElement().getAttribute("connected");
								
								if (connectedString.equals("1"))
									_connected = true;
								else
									_connected = false;
							}
							
							
							if (doc.getDocumentElement().hasChildNodes()){
								NodeList rootNodeList = doc.getDocumentElement().getChildNodes();
								
								for(int i = 0; i < rootNodeList.getLength(); i++){
									if(rootNodeList.item(i).getNodeName().toLowerCase().indexOf("color_list") == 0){
										//---COLORS SET
										NodeList colorNodeList = rootNodeList.item(i).getChildNodes();
										
										for(int j = 0; j < colorNodeList.getLength(); j++){
											//----BORDER COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("border_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_borderColor = new RGB(r, g, b);
													
												}
											}
											
											//----CONNECTION COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("connection_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_connectionColor = new RGB(r, g, b);
													
												}
											}
											
											//----SELECTION COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("selection_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_selectionColor = new RGB(r, g, b);
													
												}
											}
											
											//----FILL COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("fill_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_fillColor = new RGB(r, g, b);
													
												}
											}
											
											//----POLE COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("pole_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_poleColor = new RGB(r, g, b);
													
												}
											}
											
											//----POLE SELECTION COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("pole_selection_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_poleSelectionColor = new RGB(r, g, b);
													
												}
											}
											
											//----BG COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("bg_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_bgColor = new RGB(r, g, b);
													
												}
											}
											
											//----HOLE COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("hole_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_holeColor = new RGB(r, g, b);
													
												}
											}
											
											//----ANI COLOR SET
											if(colorNodeList.item(j).getNodeName().toLowerCase().indexOf("ani_color") == 0){
												if (colorNodeList.item(j).hasAttributes()){
													String rString = ((Element) colorNodeList.item(j)).getAttribute("r");
													String gString = ((Element) colorNodeList.item(j)).getAttribute("g");
													String bString = ((Element) colorNodeList.item(j)).getAttribute("b");
													
													int r = Integer.parseInt(rString);
													int g = Integer.parseInt(gString);
													int b = Integer.parseInt(bString);
													
													_aniColor = new RGB(r, g, b);
													
												}
											}
										}
									}
									
									//---POLE SET
									if(rootNodeList.item(i).getNodeName().toLowerCase().indexOf("pole") == 0){
										if (rootNodeList.item(i).hasAttributes()){
											String hasString = ((Element) rootNodeList.item(i)).getAttribute("hasPole");
											
											if (hasString.equals("1")){
												String xString = ((Element) rootNodeList.item(i)).getAttribute("x");
												String yString = ((Element) rootNodeList.item(i)).getAttribute("y");
												
												int x = Integer.parseInt(xString);
												int y = Integer.parseInt(yString);
												
												_pole = new Point(x, y);
												_hasPole = true;
											}											
										} 
									}
									
									//---BG IMAGE SET
									if(rootNodeList.item(i).getNodeName().toLowerCase().indexOf("bgimage") == 0){
										if (rootNodeList.item(i).hasAttributes()){
											String imgNameString =  ((Element) rootNodeList.item(i)).getAttribute("name");
											if (imgNameString.length() > 0){
												File imgFile = new File(file.getParentFile().getParentFile().getPath() + "//Pictures//" + imgNameString);
												if (imgFile.exists()){
													_imgPath = imgFile.getPath();
													
													String xString = ((Element) rootNodeList.item(i)).getAttribute("x");
													String yString = ((Element) rootNodeList.item(i)).getAttribute("y");
													
													int x = Integer.parseInt(xString);
													int y = Integer.parseInt(yString);
													
													_imgLocation = new Point(x, y);
												}
												else
													System.err.println("Image file does not exist");
											}
										} 
									}
									
									//---ANISOTROPY SET
									if(rootNodeList.item(i).getNodeName().toLowerCase().indexOf("anisotropy") == 0){
										if (rootNodeList.item(i).hasAttributes()){
											String aniNameString =  ((Element) rootNodeList.item(i)).getAttribute("name");
											if (aniNameString.length() > 0){
												File aniFile = new File(file.getParentFile().getParentFile().getPath() + "//Anisotropy//" + aniNameString);
												if (aniFile.exists()){
													
													String xString = ((Element) rootNodeList.item(i)).getAttribute("x");
													String yString = ((Element) rootNodeList.item(i)).getAttribute("y");
													String angleString = ((Element) rootNodeList.item(i)).getAttribute("angle");
													
													int x = Integer.parseInt(xString);
													int y = Integer.parseInt(yString);
													
													_aniAngle = Double.parseDouble(angleString);
													_aniPath = aniFile.getPath();
													_aniLocation = new Point(x, y);
												}
												else
													System.err.println("Anisotropy does not exist");
											}
										} 
									}
									
									//---HOLE SET
									if(rootNodeList.item(i).getNodeName().toLowerCase().indexOf("hole_list") == 0){
										NodeList holeNodeList = rootNodeList.item(i).getChildNodes();
										
										for (int j = 0; j < holeNodeList.getLength(); j++){
											if (holeNodeList.item(j).getNodeName().toLowerCase().indexOf("hole") == 0 && holeNodeList.item(j).hasAttributes()){
												String holeNameString =  ((Element) holeNodeList.item(j)).getAttribute("name");
												if(holeNameString.length() > 0){
													File holeFile = new File(file.getParentFile().getPath() + "//" + holeNameString);
													if (holeFile.exists()){
														if (!holeFile.equals(file)){
														
														String xString = ((Element) holeNodeList.item(j)).getAttribute("x");
														String yString = ((Element) holeNodeList.item(j)).getAttribute("y");
														String angleString = ((Element) holeNodeList.item(j)).getAttribute("angle");
														
														int x = Integer.parseInt(xString);
														int y = Integer.parseInt(yString);
														double angle =  Double.parseDouble(angleString);
														
														_holeList.add(holeNameString);
														_holeAngleMap.put(holeNameString, angle);
														_holeLocationMap.put(holeNameString, new Point(x, y));
														_holePathMap.put(holeNameString, holeFile.getPath());
														}
														else
															System.err.println("Object cannot be hole to itself");
													}
													else
														System.err.println("Hole " + holeNameString +  " does not exist");
													
												}
											}
										}
										
									}
									
									//---NODE SET
									if(rootNodeList.item(i).getNodeName().toLowerCase().indexOf("node_list") == 0){
										NodeList nodeNodeList = rootNodeList.item(i).getChildNodes();
										
										for(int j = 0; j < nodeNodeList.getLength(); j++){
											if(nodeNodeList.item(j).getNodeName().toLowerCase().indexOf("node") == 0 && nodeNodeList.item(j).hasAttributes()){
												
												String xString = ((Element) nodeNodeList.item(j)).getAttribute("x");
												String yString = ((Element) nodeNodeList.item(j)).getAttribute("y");				
												
												int x = Integer.parseInt(xString);
												int y = Integer.parseInt(yString);
												
												Node n = new Node(x ,y);
												_nodeList.add(n);
											}
										}
										
										for(int j = 0; j < nodeNodeList.getLength(); j++){
											if(nodeNodeList.item(j).getNodeName().toLowerCase().indexOf("node") == 0 && nodeNodeList.item(j).hasAttributes()){
												
												String xString = ((Element) nodeNodeList.item(j)).getAttribute("x");
												String yString = ((Element) nodeNodeList.item(j)).getAttribute("y");				
												
												int x = Integer.parseInt(xString);
												int y = Integer.parseInt(yString);
												
												Node ntmp = null;
												for(Node n : _nodeList){
													if (n.x == x && n.y == y){
														ntmp = n;
														break;
													}
												}
												
												
												String outxString = ((Element) nodeNodeList.item(j)).getAttribute("outx");
												String outyString = ((Element) nodeNodeList.item(j)).getAttribute("outy");
												
												if (!outxString.equals("") && !outyString.equals("")){
													int outx = Integer.parseInt(outxString);
													int outy = Integer.parseInt(outyString);
													
													for(Node n : _nodeList){
														if(n.x == outx && n.y == outy){
															ntmp.setOutNode(n);
															break;
														}
													}
												}
												
												String inxString = ((Element) nodeNodeList.item(j)).getAttribute("inx");
												String inyString = ((Element) nodeNodeList.item(j)).getAttribute("iny");
												
												if (!inxString.equals("") && !inyString.equals("")){
													int inx = Integer.parseInt(inxString);
													int iny = Integer.parseInt(inyString);
													
													for(Node n : _nodeList){
														if(n.x == inx && n.y == iny){
															ntmp.setInNode(n);
															break;
														}
													}
												}
											}
										}
									}	
								}								
							}						
						}
					}
					
					
				} catch (Exception e) {
					System.err.println("Error while opening file");
					e.printStackTrace();
				}
			}
			else
				System.err.println("File is empty");
			
		}
		else
			System.err.println("No such file was found");
	}
	
}

//TODO replace System.err with Logger
